#include "Soulgem.h"

#include "Exceptions.h"

enum {
	k_SoulgemSubLeast,
	k_SoulgemLeast,
	k_SoulgemLesser,
	k_SoulgemCommon,
	k_SoulgemGreater,
	k_SoulgemGrand,
	k_SoulgemUltraGrand
};

unsigned int SoulgemSubLeast::level() const {
	return k_SoulgemSubLeast;
}

unsigned int SoulgemLeast::level() const {
	return k_SoulgemLeast;
}

unsigned int SoulgemLesser::level() const {
	return k_SoulgemLesser;
}

unsigned int SoulgemCommon::level() const {
	return k_SoulgemCommon;
}

unsigned int SoulgemGreater::level() const {
	return k_SoulgemGreater;
}

unsigned int SoulgemGrand::level() const {
	return k_SoulgemGrand;
}

unsigned int SoulgemUltraGrand::level() const {
	return k_SoulgemUltraGrand;
}

unsigned int SoulgemIterator::level() const {
	return lv;
}

const bool Soulgem::operator ==(const Soulgem& right) const {
	return level() == right.level();
}

const bool Soulgem::operator!=(const Soulgem& right) const {
	return level() != right.level();
}

const bool Soulgem::operator < (const Soulgem& right) const {
	return level() < right.level();
}

const bool Soulgem::operator <=(const Soulgem& right) const {
	return level() <= right.level();
}

const bool Soulgem::operator > (const Soulgem& right) const {
	return level() > right.level();
}

const bool Soulgem::operator >=(const Soulgem& right) const {
	return level() >= right.level();
}

unsigned int Soulgem::operator & (const unsigned int right) const {
	return (1 << level()) & right;
}

unsigned int operator & (const unsigned int left, const Soulgem& right) {
	return left & (1 << right.level());
}

unsigned int Soulgem::operator | (const Soulgem& right) const {
	return (1 << level()) | (1 << right.level());
}

unsigned int Soulgem::operator | (const unsigned int right) const {
	return (1 << level()) | right;
}

unsigned int operator | (const unsigned int left, const Soulgem& right) {
	return left | (1 << right.level());
}

unsigned int Soulgem::operator ^ (const unsigned int right) const {
	return (1 << level()) ^ right;
}

unsigned int operator ^ (const unsigned int left, const Soulgem& right) {
	return left ^ (1 << right.level());
}

unsigned int Soulgem::operator ! () const {
	return !(1 << level());
}

SoulgemIterator::SoulgemIterator(const Soulgem* begin) {
	lv = begin->level();
}

SoulgemIterator& SoulgemIterator::operator++() {
	++lv;
	return *this;
}

SoulgemIterator SoulgemIterator::operator++(int) {
	SoulgemIterator temp = *this;
	++lv;
	return temp;
}

SoulgemIterator& SoulgemIterator::operator--() {
	--lv;
	return *this;
}

SoulgemIterator SoulgemIterator::operator--(int) {
	SoulgemIterator temp = *this;
	--lv;
	return temp;
}

const Soulgem& SoulgemIterator::operator * () const {
	switch (lv) {
		case k_SoulgemSubLeast:
			return subleast;
		case k_SoulgemLeast:
			return least;
		case k_SoulgemLesser:
			return lesser;
		case k_SoulgemCommon:
			return common;
		case k_SoulgemGreater:
			return greater;
		case k_SoulgemGrand:
			return grand;
		case k_SoulgemUltraGrand:
			return ultra;
		default:
			throw unknown_soulgem();
	}
}
